#pragma once
#include "base/function.hpp"
#include "net/connect.h"

#include "MyRpc/dataformat.h"
#include "MyRpc/rpc.h"
#include "MyRpc/rpccall.hpp"

#include <vector>
namespace myrpc{
class Message{
 public:
  // data_type种类
  ~Message() = default;
  bool Init_message(uint32_t type,message_func func);
  void Init_rpc();
  base::Rpc* Get_rpc();
  uint Consume_message(net_tools::net::Connect* connect,char* buf,uint size);
  static uint32_t Analyze_head(char* buf);
  static void Creat_head(uint32_t type,char* buf);
  static Message* Get_singleton(){
    static Message message;
    return &message;
  };

  template <typename... Datas>
  static bool Make_rpc(net_tools::net::Connect* connect,uint32_t type,char* buf,bool ret,Datas&&... datas){
    Creat_head(4,buf);
    if(!connect->Write(buf,4 + base::Rpccall<>::Make(type,buf + 4,ret,std::forward<Datas>(datas)...))){
      return false;
    }
    return true;
  };
 private:
  Message(uint64_t message_size = base::Dataformat::data_type_size_);

  std::vector<message_func> func_vec_;
  uint32_t                  head_size_;
  base::Rpc                 rpc_;
};

} // namespace myrpc